package com.zhang.sdk.utils.log;

import android.annotation.SuppressLint;
import android.content.Context;

import androidx.annotation.NonNull;
/**
 * 描述：新的自定义异常捕获处理
 *
 * @author Abel
 * @version 1.0
 * @date 2019/7/8 15:14
 */
public class ExceptionHandleNew implements Thread.UncaughtExceptionHandler {
    private static final String TAG = "ExceptionHandle";
    /**
     * 系统默认的UncaughtException处理类
     */
    private Thread.UncaughtExceptionHandler defaultExceptionHandler;
    /**
     * ExceptionHandle实例
     */
    @SuppressLint("StaticFieldLeak")
    private static ExceptionHandleNew instance;
    private Context mContext;
    /**
     * 日志文件所在目录
     */
    private String mLogDir;
    /**
     * 日志文件名称
     */
    private String mLogFileName;

    private ExceptionHandleNew() {
    }

    public static synchronized ExceptionHandleNew getInstance() {
        if (instance == null) {
            instance = new ExceptionHandleNew();
        }
        return instance;
    }

    /**
     * 初始化
     *
     * @param logDir      Crash日志所在的文件夹
     * @param logFileName Crash日志的文件名
     */
    public void init(Context context, @NonNull String logDir, @NonNull String logFileName) {
        this.mContext = context;
        this.mLogDir = logDir;
        this.mLogFileName = logFileName;
        // 获取系统默认的UncaughtException处理器
        defaultExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
        // 设置该ExceptionHandle为程序的默认处理器
        Thread.setDefaultUncaughtExceptionHandler(this);
    }

    /**
     * 当UncaughtException发生时会转入该函数来处理
     */
    @Override
    public void uncaughtException(Thread thread, Throwable ex) {
        LogUtil.e(TAG, "============>捕获到异常");

        boolean handleException = handleException(ex);
        if (!handleException && defaultExceptionHandler != null) {
            LogUtil.e(TAG, "============>交由系统defaultExceptionHandler处理出现的异常");
            defaultExceptionHandler.uncaughtException(thread, ex);
        } else {
            LogUtil.e(TAG, "============>自定义异常捕获，拦截系统的异常处理，避免崩溃");
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                LogUtil.e(TAG, "error : InterruptedException");
            }
            // 退出程序
            android.os.Process.killProcess(android.os.Process.myPid());
            System.exit(1);
        }
    }

    /**
     * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成.
     *
     * @return true:如果处理了该异常信息;否则返回false.
     */
    private boolean handleException(Throwable ex) {
        if (null == ex) {
            return false;
        }
        // 保存日志到文件
        ErrorLogUtil.saveException(mContext, ex, mLogDir, mLogFileName);
        return false;
    }
}
